package com.wjw.spring5.proxy;

import com.wjw.spring5.dao.UserDao;
import com.wjw.spring5.dao.impl.UserDaoImpl;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

/**
 * @author wjw
 * @date 2021年11月01日 17:41
 * 匿名内部类的方式创建代理对象
 */
public class JDKProxy {
    private UserDao dao = new UserDaoImpl(); // 创建需要被代理的对象
    Class[] interfaces = {UserDao.class};
    public UserDao getUserProxy() {
        return (UserDao) Proxy.newProxyInstance(JDKProxy.class.getClassLoader(),
                dao.getClass().getInterfaces(), new InvocationHandler() {
                    /**
                     * 第二个参数写法
                     * Class[] interfaces = {UserDao.class};
                     * new Class[]{UserDao.class}
                     */
                    /**
                     * InvocationHandler接口只定义了一个invoke方法，因此对于这样的接口，我们不用单独去定义一个类来实现该接口，
                     * 而是直接使用一个匿名内部类来实现该接口，new InvocationHandler() {}就是针对InvocationHandler接口的匿名实现类
                     */
                    /**
                     * 在invoke方法编码指定返回的代理对象干的工作
                     * proxy : 把代理对象自己传递进来
                     * method：把代理对象当前调用的方法传递进来
                     * args:把方法参数传递进来
                     *
                     * 当调用代理对象的方法时，
                     * 实际上执行的都是invoke方法里面的代码，
                     * 因此我们可以在invoke方法中使用method.getName()就可以知道当前调用的是代理对象的哪个方法
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        if (method.getName().equals("add")) {
                            System.out.println("将要执行添加用户操作，参数(name)为：" + Arrays.toString(args));
                        }
                        if (method.getName().equals("find")) {
                            System.out.println("将要执行查询用户操作，参数(name)为：" + Arrays.toString(args));
                        }
                        return method.invoke(dao, args);
                    }
                });
    }
}
